package com.example.service.impl;

import com.example.entity.SysMenu;
import com.example.entity.SysPermission;
import com.example.entity.SysRole;
import com.example.mapper.SysMenuMapper;
import com.example.mapper.SysPermissionMapper;
import com.example.mapper.SysRoleMapper;
import com.example.service.SysRoleService;
import com.example.utils.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * TODO
 *
 * @Comment：最难的一次作业
 * @Date: 2023/12/1
 */
@Service
@Slf4j
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysPermissionMapper permissionMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private RedisUtils redisUtils;

    

    @Override
    public Result findPage(QueryInfo queryInfo) {
        log.info("开始角色数据分页-->页码{}, --->{}页数--->查询内容{}",queryInfo.getPageNumber(), queryInfo.getPageSize(),
                queryInfo.getQueryString());
        PageHelper.startPage(queryInfo.getPageNumber(), queryInfo.getPageSize());
        Page<SysRole> page = roleMapper.findPage(queryInfo.getQueryString());

        long total = page.getTotal();
        log.info("分页总数据数: {}", total);

        List<SysRole> result = page.getResult();
        result.forEach(item -> {
            // 查询该角色的父级菜单信息
            List<SysMenu> menus = menuMapper.findByRoleId(item.getId());
            menus.forEach(menu -> {
                // 迭代查询的父级菜单，根据父级菜单id和角色id查询所有子菜单
                List<SysMenu> children = menuMapper.findByRoleIdAndParentId(menu.getId(), item.getId());
                // 将查到的子级菜单赋值给父级菜单
                menu.setChildren(children);
            });
            // 将查到的菜单信息赋值给角色
            item.setMenus(menus);

            // 查询该角色权限信息
            List<SysPermission> permissions = permissionMapper.findByRoleId(item.getId());
            item.setPermissions(permissions);
        });
        log.info("查询的总条数-->{}", total);
        log.info("分页列表-->{}", result);
        return PageResult.pageResult(total, result);
    }

    @Transactional
    @Override
    public Result insert(SysRole role) {
        log.info("查询角色信息是否存在");
        SysRole role1 =  roleMapper.findByLabel(role.getLabel());
        if (role1 != null) {
            return Result.fail("角色已存在！");
        }

        // 先插入角色，再做以下判断
        roleMapper.insert(role);
        // 判断传入的角色信息是否带有权限信息需要插入
        if (!role.getPermissions().isEmpty()) {
            log.info("开始插入角色与权限关系信息");
            role.getPermissions().forEach(item -> roleMapper.insertPermissions(role.getId(), item.getId()));

        }
        // 判断传入的角色信息是否带有菜单信息需要插入
        if (!role.getMenus().isEmpty()) {
            log.info("开始插入角色与菜单关系信息");
            role.getMenus().forEach(item -> roleMapper.insertMenus(role.getId(), item.getId()));
        }
        redisUtils.delValue("userInfo_" + SecurityUtils.getUsername());
        return Result.success("添加角色信息成功！");
    }

    @Transactional
    @Override
    public Result update(SysRole role) {

        // 先更新角色信息，后面再更新对应的菜单和权限
        roleMapper.update(role);
        // 判断修改的角色是否带有权限信息
        if (!role.getPermissions().isEmpty()) {
            log.info("先删除角色旧的权限信息");
            roleMapper.deletePermissionById(role.getId());
            log.info("再插入角色新的权限信息");
            role.getPermissions().forEach(item -> roleMapper.insertPermissions(role.getId(), item.getId()));
        }
        // 判断修改的角色是否带有菜单信息
        if (!role.getMenus().isEmpty()) {
            log.info("先删除角色旧的菜单信息");
            roleMapper.deleteMenuById(role.getId());
            log.info("再插入角色新的菜单信息");
            role.getMenus().forEach(item -> roleMapper.insertMenus(role.getId(), item.getId()));
        }

        redisUtils.delValue("userInfo_" + SecurityUtils.getUsername());
        return Result.success("修改角色数据成功！");
    }

    @Override
    public Result delete(Long id) {
        log.info("查询角色信息是否存在");
        SysRole role = roleMapper.findById(id);
        if (role == null) {
            return Result.fail("角色不存在！");
        }

        log.info("查询该角色信息下是否有菜单和权限");
        // 获取角色的父级菜单信息
        List<SysMenu> menus = menuMapper.findByRoleId(id);
        List<SysMenu> children = new ArrayList<>();
        menus.forEach(item -> children.addAll(menuMapper.findByRoleIdAndParentId(item.getId(), id)));
        // 判断菜单信息是否为空
        if (!menus.isEmpty() || !children.isEmpty()) {
            return Result.fail("删除失败，该角色下拥有菜单信息，请先删除对应的菜单信息");
        }
        // 判断权限信息是否为空
        if (!permissionMapper.findByRoleId(id).isEmpty()) {
            return Result.fail("删除失败，该角色下拥有权限信息，请先删除对应的权限信息");
        }


        roleMapper.delete(id);
        redisUtils.delValue("userInfo_" + SecurityUtils.getUsername());
        return Result.success("删除角色数据成功！");
    }

    @Override
    public Result findAll() {
        return Result.success("权限角色信息成功", roleMapper.findAll());
    }


}
